package com.molichuxing.gateway.bff.car.services.impl;

import java.math.BigDecimal;
import java.util.*;

import javax.annotation.Resource;

import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.result.ResponseCodeEnum;
import com.molichuxing.framework.result.ResponseResult;
import com.molichuxing.framework.utils.CollectionUtils;
import com.molichuxing.framework.utils.DingTalkUtil;
import com.molichuxing.gateway.bff.car.entity.response.*;
import com.molichuxing.gateway.utils.TokenUtil;
import com.molichuxing.gateway.utils.entity.UserEntity;
import com.molichuxing.services.business.dto.request.modify.OrderReturnDisputeDisposalsModifyBizDto;
import com.molichuxing.services.business.dto.request.modify.OrderReturnPdiModifyBizDto;
import com.molichuxing.services.business.service.OrderReturnBizService;
import com.molichuxing.services.business.service.VehicleBizService;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.ContractTypeEnum;
import com.molichuxing.services.property.StockCarCarStatusEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.gateway.bff.car.convertor.Convert;
import com.molichuxing.gateway.bff.car.services.CarCheckBffService;
import com.molichuxing.gateway.property.CarCheckClientEnum;
import com.molichuxing.services.business.dto.response.CarCheckDto;
import com.molichuxing.services.business.service.CarCheckBizService;
import com.molichuxing.services.infrastructure.dto.request.modify.CheckModifyDto;
import com.molichuxing.services.infrastructure.dto.request.modify.DisPdiCheckModifyDto;
import com.molichuxing.services.infrastructure.dto.request.modify.PdiCheckModifyDto;
import com.molichuxing.services.property.CarCheckStatusEnum;
import com.molichuxing.services.property.CarsTypeEnum;

/**
 * 车辆检验bff
 *
 */
@Service("carCheckBffService")
public class CarCheckBffServiceImpl implements CarCheckBffService {

	private static final Logger logger = LoggerFactory.getLogger(CarCheckBffServiceImpl.class);

	@Resource
	private CarCheckBizService carCheckBizService;

	@Resource
	private CheckService checkService;

	@Resource
	private CarDetailService carDetailService;

	@Resource
	private VehicleService vehicleService;

	@Resource
	private VehicleColorService vehicleColorService;

	@Resource
	private VehicleModleService vehicleModleService;

	@Resource
	private VehicleMakeService vehicleMakeService;

	@Resource
	private CarService carService;

	@Resource
	private CheckImageService checkImageService;

	@Resource
	private CheckPreparationService checkPreparationService;

	@Resource
	private CheckDisputeService checkDisputeService;

	@Resource
	private StoreService storeService;

	@Resource
	private IovCarService iovCarService;

	@Resource
	private TokenUtil tokenUtil;

	@Resource
	private ContractService contractService;

	@Resource
	private OrderReturnBizService orderReturnBizService;

	@Resource
	private VehicleBizService vehicleBizService;

	@Resource
	private StockCarService stockCarService;

	@Resource
	private DealerService dealerService;

	@Value("${profiles.active.explain}")
	private String active;

	@Resource
	private VehiclePictureService vehiclePictureService;


	@Override
	public Paged<CarCheckVo> getCarCheckList(Map<String, Object> selectParams) {
		logger.info("车辆检验 新车检验列表页 入参 >>" + JSON.toJSONString(selectParams));
		Paged<CarCheckVo> carCheckVoList = new Paged<CarCheckVo>();
		Paged<CarCheckDto> dto = carCheckBizService.getCarCheck(
				ObjectCastUtil.castString(selectParams.get("licencePlate")),
				ObjectCastUtil.castString(selectParams.get("vin")),
				selectParams.get("carType") == null ? null
						: CarsTypeEnum.getEnum(ObjectCastUtil.castInt(selectParams.get("carType"))),
				selectParams.get("status") == null ? null
						: CarCheckStatusEnum.getEnum(ObjectCastUtil.castInt(selectParams.get("status"))),
				selectParams.get("startCheckTime") == null ? null
						: DateUtil.parseDateTime(ObjectCastUtil.castString(selectParams.get("startCheckTime"))),
				selectParams.get("endCheckTime") == null ? null
						: DateUtil.parseDateTime(ObjectCastUtil.castString(selectParams.get("endCheckTime"))),
				ObjectCastUtil.castInteger(selectParams.get("pageSize")) == null ? 10
						: ObjectCastUtil.castInteger(selectParams.get("pageSize")),
				ObjectCastUtil.castInteger(selectParams.get("pageNum")) == null ? 1
						: ObjectCastUtil.castInteger(selectParams.get("pageNum")));
		carCheckVoList = Convert.toPagedCarCheckVo(dto);
		List<CarCheckVo> dataList = carCheckVoList.getList();
		if (CollectionUtils.isNotEmpty(dataList)) {
			//获取车型
			List<Integer> carIds = getVehicleIds(dataList);
			Map<Integer, String> vehicleMap = null;
			if(null != carIds) {
				vehicleMap = vehicleBizService.getVehicleFullName(carIds);
			}
			Map<Integer, List<VehiclePictureDto>> pictureMap = vehiclePictureService.getVehiclePictureByVehicleIds(carIds);
			for (CarCheckVo checkVo : dataList) {
				if (vehicleMap != null && vehicleMap.size() > 0) { //设置车型
					checkVo.setVehicleName(vehicleMap.get(checkVo.getVehicleId()));
				}
				if (pictureMap != null && pictureMap.size() > 0) { //设置车型
					for(VehiclePictureDto vehiclePictureDto : pictureMap.get(checkVo.getVehicleId())) {
						if(vehiclePictureDto.getIsWhiteBg() && 1 == vehiclePictureDto.getPicDetailType()) {
							checkVo.setVehicleImg(vehiclePictureDto.getServerUrl());
							break;
						}

					}
				}
			}
		}
		logger.info("车辆检验 新车检验列表页 出参 >>" + JSON.toJSONString(carCheckVoList));
		return carCheckVoList;
	}

	@Override
	public List<CarCheckVo> getCarCheckListByCarId(Integer carId) {
		List<CarCheckVo> result = Convert.toCarCheckVoList(carCheckBizService.getCheckByCarId(carId));
		if ((null == result) || (result.size() == 0)) {
			return null;
		}
		for (CarCheckVo carCheck : result) {
			if(null != carCheck.getCheckClient()) {
				if (carCheck.getCheckClient() == CarCheckClientEnum.MOLI.getValue()) {
					carCheck.setOpName(CarCheckClientEnum.MOLI.getName() + "-" + carCheck.getOpName());
				} else if (carCheck.getCheckClient() == CarCheckClientEnum.DEALER.getValue()) {
					carCheck.setOpName(CarCheckClientEnum.DEALER.getName() + "-" + carCheck.getOpName());
				}
			}

		}
		return result;
	}

	@Override
	public CarBasicVo getCheckBasicInfo(Integer checkId) throws Exception {
		CarBasicVo vo = new CarBasicVo();
		if (checkId == null) {
			return vo;
		}
		// 根据检验id 获取 车辆id
		CheckDto checkDto = checkService.getById(checkId);
		if (checkDto == null) {
			return vo;
		}
		// 车辆信息
		CarDto carDto = carService.getCarById(checkDto.getCarId());
		// 车辆详情
		CarDetailDto carDetailDto = carDetailService.getCarDetailById(carDto.getId());

		// 根据车型id 获取 车型相关信息
		VehicleDto vehicleDto = vehicleService.getVehicleByVehicleId(carDto.getVehicleId());
		// 根据车型id 获取车系 获取子品牌名称
		VehicleMakeDto vehicleMakeDto = vehicleMakeService.getVehicleMakeDtoById(
				vehicleModleService.getVehicleModleDtoById(vehicleDto.getSeriesId()).getVehicleMakeId());
		// 根据颜色id 获取车辆颜色
		VehicleColorDto vehicleColorDto = vehicleColorService
				.getVehicleColorByvehicleColorId(carDto.getVehicleColorId());
		vo.setColor(vehicleColorDto.getName());
		vo.setLicencePlate(carDto.getLicencePlate());
		vo.setVin(carDto.getVin());
		vo.setName(vehicleDto.getName());
		vo.setVehicleName(vehicleMakeDto.getName());
		vo.setYear(vehicleDto.getYear());
		vo.setStatus(CarCheckStatusEnum.getName(Integer.valueOf(checkDto.getStatus())));
		vo.setEngineCode(carDetailDto.getEngineCode());
		vo.setOrderCode(checkDto.getOrderCode());
		StoreDto storeDto = storeService.getStoreById(checkDto.getReturnStoreId());
		vo.setReturnStoreId(checkDto.getReturnStoreId());
		vo.setReturnStoreName(storeDto.getFullName());
		return vo;
	}

	@Override
	public PdiCheckVo getPdiCheckNewInfo(Integer checkId) throws Exception {
		PdiCheckVo vo = new PdiCheckVo();
		if (checkId != null) {
			CheckDto checkDto = checkService.getById(checkId);
			CheckDisputeDto checkDisputeDto = checkDisputeService.getByCheckId(checkId);
			if (checkDto != null) {
				vo = Convert.toPdiCheckVo(checkDto, checkDisputeDto);

 				//查询还车单
				if (checkDto.getOrderCode() != null) {
					List<ContractDto> contractByOrderCode = contractService.getContractByOrderCode(checkDto.getOrderCode(), ContractTypeEnum.MILEAGE_BAG_RETURN_CAR.getValue());
					if (CollectionUtils.isNotEmpty(contractByOrderCode)) {
						vo.setRelativePath(contractByOrderCode.get(0).getContractPath()); //还车单图片地址
					}
				}
				return vo;
			} else {
				return vo;
			}
		} else {
			return vo;
		}
	}

	@Override
	public CheckVo getCheckNewInfo(Integer checkId) throws Exception {
		CheckVo vo = new CheckVo();
		if (checkId != null) {
			CheckDto checkDto = checkService.getById(checkId);
			if (checkDto != null) {
				vo = Convert.toCheckVo(checkDto);

				return vo;
			} else {
				return vo;
			}
		} else {
			return vo;
		}
	}

	@Override
	public CheckImageVo getCheckImageInfo(Integer checkId) {
		CheckImageVo image = new CheckImageVo();
		if (checkId == null) {
			return image;
		}
		List<CheckImageDto> imageDto = checkImageService.getCheckImageByCheckId(checkId);
		if (imageDto != null && imageDto.size() <= 0) {
			return image;
		}
		image = Convert.toCheckImageVoBean(imageDto);
		return image;
	}

	@Override
	public CheckPreparationVo getCheckPreparationInfo(Integer checkId) {
		CheckPreparationVo checkPreparationVo = new CheckPreparationVo();
		if (checkId == null) {
			return checkPreparationVo;
		}
		CheckPreparationDto dto = checkPreparationService.getCheckPreparation(checkId);
		checkPreparationVo = Convert.toCheckPreparationVo(dto);
		return checkPreparationVo;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
	public Boolean checkCar(CheckModifyDto checkModifyDto) throws Exception {
		boolean checkResult = carCheckBizService.checkCar(checkModifyDto);
		if (checkResult) {
			CheckDto check = checkService.getById(checkModifyDto.getCheckId());
			if (check != null) {
				boolean carStatusResult = stockCarService.modifyCarStatus(check.getCarId(), StockCarCarStatusEnum.RENTED.getValue());
				if (carStatusResult) {
					return true;
				} else {
					throw new BizException(ResponseCodeEnum.UNKNOWN_ERROR.getCode(), "修改车辆仓储失败");
				}
			}
		}
		return false;
	}

	@Override
	public Paged<CarCheckVo> getPdiCarCheck(Map<String, Object> selectParams) throws Exception {
		Paged<CarCheckVo> carCheckVoList = new Paged<CarCheckVo>();
		List<Integer> carIdsByOrderCode = new ArrayList<>();
		Paged<CarCheckDto> dto = carCheckBizService.getPdiCarCheck(
				ObjectCastUtil.castString(selectParams.get("licencePlate")),
				ObjectCastUtil.castString(selectParams.get("vin")),
				selectParams.get("orderCode") == null ? null : ObjectCastUtil.castLong(selectParams.get("orderCode")),
				ObjectCastUtil.castInteger(selectParams.get("returnStoreId")),
				selectParams.get("status") == null ? null
						: CarCheckStatusEnum.getEnum(ObjectCastUtil.castInt(selectParams.get("status"))),
				ObjectCastUtil.castInteger(selectParams.get("pageSize")) == null ? 10
						: ObjectCastUtil.castInteger(selectParams.get("pageSize")),
				ObjectCastUtil.castInteger(selectParams.get("pageNum")) == null ? 1
						: ObjectCastUtil.castInteger(selectParams.get("pageNum")),
				null);
		carCheckVoList = Convert.toPagedCarCheckVo(dto);
		List<CarCheckVo> dataList = carCheckVoList.getList();
		if (CollectionUtils.isNotEmpty(dataList)) {

			List<Long> orderCodeList = new ArrayList<>();

			for (CarCheckVo checkVo : dataList) {
				StoreDto storeDto = storeService.getStoreById(checkVo.getReturnStoreId());
				if (storeDto != null) {
					DealerDto dealer = dealerService.getDealerById(storeDto.getDealerId());
					checkVo.setReturnStoreId(storeDto.getStoreId());
					if (dealer != null) {
						checkVo.setReturnStoreName(dealer.getShortName() +"-"+ storeDto.getShortName());
					} else {
						checkVo.setReturnStoreName(storeDto.getShortName());
					}
				}
				orderCodeList.add(checkVo.getOrderCode());
			}

			//获取还车单
			Map<Long, List<ContractDto>> contractMapByOrderCode = null;
			if (CollectionUtils.isNotEmpty(orderCodeList)) {
				contractMapByOrderCode = contractService.getContractMapByOrderCode(orderCodeList, ContractTypeEnum.MILEAGE_BAG_RETURN_CAR.getValue()); //还车单对象集合
			}

			//获取车型
			List<Integer> carIds = getVehicleIds(dataList);
			Map<Integer, String> vehicleMap = null;
			if(null != carIds) {
				vehicleMap = vehicleBizService.getVehicleFullName(carIds);
			}

			Map<Integer, List<VehiclePictureDto>> pictureMap = vehiclePictureService.getVehiclePictureByVehicleIds(carIds);
			for (CarCheckVo checkVo : dataList) {
				if (vehicleMap != null && vehicleMap.size() > 0) { //设置车型
					for(VehiclePictureDto vehiclePictureDto : pictureMap.get(checkVo.getVehicleId())) {
						if(vehiclePictureDto.getIsWhiteBg() && 1 == vehiclePictureDto.getPicDetailType()) {
							checkVo.setVehicleImg(vehiclePictureDto.getServerUrl());
							break;
						}

					}
				}
			}

			for (CarCheckVo checkVo : dataList) {
				if (contractMapByOrderCode != null && contractMapByOrderCode.size() > 0) { //设置还车单地址pdf地址
					List<ContractDto> contractDtoList = contractMapByOrderCode.get(checkVo.getOrderCode());
					if (CollectionUtils.isNotEmpty(contractDtoList)) {
						ContractDto contractDto = contractDtoList.get(0);
						checkVo.setRelativePath(contractDto.getContractPath());
					}
				}


				if (vehicleMap != null && vehicleMap.size() > 0) { //设置车型
					checkVo.setVehicleName(vehicleMap.get(checkVo.getVehicleId()));
				}

				checkVo.setCarTypeStr(CarsTypeEnum.getName(checkVo.getCarType()));
			}
		}
		return carCheckVoList;
	}

	private List<Integer> getVehicleIds(List<CarCheckVo> dataList) {
		List<Integer> vehicleIds = null;

		if (CollectionUtils.isNotEmpty(dataList)) {
            vehicleIds = new ArrayList<>();
			for(CarCheckVo vo: dataList) {
                vehicleIds.add(vo.getVehicleId());
			}
		}
		return vehicleIds;
	}

	@Override
	public Boolean discussPdiCheck(DisPdiCheckModifyDto disPdiCheckModifyDto) throws Exception {
		UserEntity currentLoginUser = tokenUtil.getUser(); //当前登录用户

		CheckDto checkDto = checkService.getById(disPdiCheckModifyDto.getCheckId());
		if (checkDto != null) {
			boolean disputeResult = carCheckBizService.modifyCheckDispute(disPdiCheckModifyDto.getCheckId(),
					disPdiCheckModifyDto.getDiscussLossFee(), disPdiCheckModifyDto.getRemark(), currentLoginUser.getRealName());
			if (disputeResult) {

				try {
					OrderReturnDisputeDisposalsModifyBizDto dto = new OrderReturnDisputeDisposalsModifyBizDto();
					dto.setDamageFee(disPdiCheckModifyDto.getDiscussLossFee());
					dto.setOrderCode(checkDto.getOrderCode());
					dto.setDisposalsId(currentLoginUser.getAccountId());
					dto.setDisposalsName(currentLoginUser.getRealName());
					Boolean modifyOrder = orderReturnBizService.modifyReturnDisputeDisposals(dto);
					if (modifyOrder == null || !modifyOrder) {
						DingTalkUtil.exceptionSend(active + "pdi争议处理修改订单失败，checkId = " +disPdiCheckModifyDto.getCheckId() + "，orderCode=" +checkDto.getOrderCode());
						return false;
					}
					return true;
				} catch (Exception e) {
					DingTalkUtil.exceptionSend(active + "pdi争议处理修改订单失败，checkId = " +disPdiCheckModifyDto.getCheckId() + "，orderCode=" +checkDto.getOrderCode());
					throw new Exception(e.getMessage(), e);
				}
			} else {
				return false;
			}
		}
		return false;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
	public Boolean pdiCheckCar(PdiCheckModifyDto pdiCheckModifyDto) throws Exception {
		CheckDto check = checkService.getById(pdiCheckModifyDto.getCheckId());
		if (check.getStatus() != CarCheckStatusEnum.NO_CHECK.getValue()) { //只有待检验的车才能够检验
			throw new BizException(ResponseCodeEnum.UNKNOWN_ERROR.getCode(), "车辆必须是未检验状态才可以检验");
		}
		CarDto car = carService.getCarById(check.getCarId());
		if (car == null) {
			throw new BizException(ResponseCodeEnum.UNKNOWN_ERROR.getCode(), "车辆不存在");
		}

		if (check != null) {
            pdiCheckModifyDto.setOpName(tokenUtil.getUser().getRealName()); //操作人
			boolean checkCarResult = carCheckBizService.pdiCheckCar(pdiCheckModifyDto);
			if (checkCarResult) {

				//修改仓库车辆类型
				boolean carStatusResult = false;
				if(car.getVehicleType() == CarsTypeEnum.NEW_CAR.getValue()) { //如果是新车，不可运行
					carStatusResult = stockCarService.modifyCarStatus(car.getId(), StockCarCarStatusEnum.NOT_RENT.getValue());
				} else { //如果是二手车，可运营
					carStatusResult = stockCarService.modifyCarStatus(check.getCarId(), StockCarCarStatusEnum.RENTED.getValue());
				}

				if (carStatusResult) {
					try {
						UserEntity currentLoginUser = tokenUtil.getUser();
						OrderReturnPdiModifyBizDto dto = new OrderReturnPdiModifyBizDto(); //pid检测成功后修改订单
						dto.setOrderCode(check.getOrderCode());
						dto.setDamageFee(pdiCheckModifyDto.getLossFee());
						dto.setCheckId(currentLoginUser.getAccountId()); //检验人id
						dto.setCheckName(currentLoginUser.getRealName()); //检验人姓名
						Boolean modifyOrderResult = orderReturnBizService.modifyReturnPdi(dto);
						if (modifyOrderResult == null || !modifyOrderResult) {
							DingTalkUtil.exceptionSend(active + "pdi检验修改订单失败，checkId = " +check.getId() + "，orderCode=" +check.getOrderCode());
							return false;
						}
						return true;
					} catch (Exception e) {
						DingTalkUtil.exceptionSend(active + "pdi检验修改订单失败，checkId = " +check.getId() + "，orderCode=" +check.getOrderCode());
						throw new Exception(e.getMessage(), e);
					}
				}
			}
		}
		return false;
	}

}
